﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CutAways.Geometry
{
	[Serializable]
    class Camera
    {
        private Vector eye, center, up;
        private float multiplier = 10.0f;
        private float angle = (float)(Math.PI / 720.0);

        public Camera()
        {
            eye = new Vector();
            center = new Vector();
            up = new Vector();
            Reset();
        }

        public void Reset()
        {
            eye = new Vector(0, 0, 1f);
            center = new Vector(0, 0, 0);
            up = new Vector(0, 1f, 0);
        }

        public Vector Eye
        {
            get { return eye; }
			set { eye = value; }
        }

        public Vector Center
        {
            get { return center; }
			set { center = value; }
        }

        public Vector Up
        {
            get { return up; }
			set { up = value; }
        }

        public void moveForward(float fps)
        {
            Vector dir = center - eye;
            eye += dir * multiplier / fps;
        }

        public void moveBackward(float fps)
        {
            Vector dir = center - eye;
            eye -= dir * multiplier / fps;
        }

        public void strafeLeft(float fps, int howMuch)
        {
            eye.Rotate(howMuch * angle, up);
        }

        public void strafeRight(float fps, int howMuch)
        {
            eye.Rotate(howMuch * (-angle), up);
        }

        public void strafeUp(float fps, int howMuch)
        {
            Vector dir = center - eye;
            Vector axis = dir * up;
            axis.Normalize();

            eye.Rotate(howMuch * angle, axis);
            up.Rotate(howMuch * angle, axis);
        }

        public void strafeDown(float fps, int howMuch)
        {
            Vector dir = center - eye;
            Vector axis = dir * up;
            axis.Normalize();

            eye.Rotate(howMuch * (-angle), axis);
            up.Rotate(howMuch * (-angle), axis);
        }

        public void lookLeft(float fps)
        {
            center += Vector.Cross(up, center) * multiplier / fps;
            center.Normalize();
        }

        public void lookRight(float fps)
        {
            center -= Vector.Cross(up, center) * multiplier / fps;
            center.Normalize();
        }

        public void lookUp(float fps)
        {
            center += up * multiplier / fps;
            center.Normalize();
        }

        public void lookDown(float fps)
        {
            center -= up * multiplier / fps;
            center.Normalize();
        }

        public override string ToString()
        {
            return eye.ToString() + "\n" + center.ToString() + "\n" + up.ToString();
        }

		public Camera Clone()
		{
			Camera clone = new Camera();
			clone.eye = this.eye;
			clone.center = this.center;
			clone.up = this.up;
			clone.multiplier = this.multiplier;
			clone.angle = this.angle;
			return clone;
		}
    }
}
